<?php
/**
 * PHP.aide + YEAP project
 * Storage Driver for Storage[Engine]
 * based on PDO
 *
 * GPL v.2
 * (cc) VS aka Virtual Stalker, 2009
 * call@2128506.su
 *
 * энжой! =;)
 * */

include_once '../Accessor.class.php';
class PDOAccessor extends Accessor
{
	protected $sth;
	protected $sql;
	protected $data;
	public static $fetchMode = PDO::FETCH_ASSOC;
	/**
	 * секция инициализации
	 * */
	function init()
	{
		if (!is_object($this->driver))
		{
			if (!isset($GLOBALS['depot']))
				$GLOBALS['depot'] = new PDO(DB_DSN);

			$this->driver = $GLOBALS['depot'];	//	бред какой-то. зачем я привязал драйвер к модулю? в этом был какой-то тайный смысл
		}
		if (is_object($this->driver))
		{
			//	http://ru.php.net/manual/en/pdo.setattribute.php
			$this->driver->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
			$this->driver->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
			$this->driver->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);
			$this->driver->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
		}
	}

	protected function _trim($sql)
	{
		return $this->sql = trim(preg_replace(array("~(:[a-z]+:|[\r\n]*)~imu",'~\t~miu','~[ ]{2,}~imu'),array('',' ',' '),$sql));
	}
	protected function _bind($data,$bind=true)
	{
		$this->data = array();
		if (is_array($data))
		{
			foreach( $data as $name => $val )
			{
				if (false!==strpos($this->sql,$name))	//	надеемся, что все плейсхолдеры как бы уникальны
				{
					$this->data[$name] = $val;
					//_log(array($name=>$val));
					//$sth->bindParam($name,$val,PDO::PARAM_STR);
					if ($bind)
					{
						if (is_int($val))	//	только инты, остальное прохавает
							$this->sth->bindValue($name,$val,PDO::PARAM_INT);
						else
							$this->sth->bindValue($name,$val,PDO::PARAM_STR);
					}
				}
			}
			return $this->data;
		}
		else
			return $data;
	}

	public function __call($method,$args)
	{
		return is_object($this->sth) ? call_user_func_array(array($this->sth,$method),$args) : null ;
	}

	public function query($sql=null,$data=null)
	{
		if (is_null($data))
			$data = array();
		$this->sql = $this->_trim($sql);

		$this->sth = $this->driver->prepare($this->sql);
		$this->sth->setFetchMode(self::$fetchMode);
		return $this->sth->execute($this->data);
	}

	/**
	 *
	 *	*/
	function run($sql=null,$data=null)
	{
		if (is_null($data))
			$data = array();

		$sql = trim(preg_replace(array("~(:[a-z]+:|[\r\n]*)~imu",'~\t~miu','~[ ]{2,}~imu'),array('',' ',' '),$sql));
		//	заменяем паттерны и много пробелов
		//	потом покажу зачем. это осталось от простого sql-конструктора

		//	сюда лог запросов включить. вызвать событие
		//new DBQueryLogEvent($this->sql,$data);
_log('SQL',$sql);
		$sth = $this->driver->prepare($sql);
		//$sth->setFetchMode(PDO::FETCH_OBJ);
		$sth->setFetchMode(PDO::FETCH_ASSOC);
		$req_data = array();
		if (is_array($data))
			foreach( $data as $name => $val )
			{
				//	эт шиза ваще блин
				if (false!==strpos($sql,$name))	//	надеемся, что все плейсхолдеры как бы уникальны
				{
					$req_data[$name] = $val;
					//_log(array($name=>$val));
					//$sth->bindParam($name,$val,PDO::PARAM_STR);
					$sth->bindValue($name,$val,PDO::PARAM_STR);
				}
			}

		//new DBQueryLogEvent($this->sql,$sth,$data);
//$db->beginTransaction();

		$res = $sth->execute();

		if ( 0 === strpos($sql,'SELECT') )	//	если селект обрабатываем
		{
			if ( false === $res )
			{
				return false;
			}
			else
			{
				$r = $sth->fetchAll();
_log('RES',$r,$sth->rowCount());
				return $r;
			}
		}
		else
		{
			return $sth->rowCount();
		}
	}
	function forDB($data)
	{
		$ar = array();
		foreach($data as $name => $item)
			$ar[':'.$name] = (string)$item;
		return $ar;
	}
}
?>